package net.sinodata.smartframework.threadpool.base;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Description: 队列线程池 队列线程池为每个队列维护一个队列线程，队列线程中维护了一个线程池，队列线程负责获取任务并将任务交由线程池处理
 * 
 * @author: yinliangyun
 * @date: 2021-5-19
 */
public class QueueThreadPoolManager {
	
	private static final Logger logger = LoggerFactory.getLogger(QueueThreadPoolManager.class);

	private static Map<String, String> classMaps = new HashMap<String, String>();

	public static void setClassMap(String clazzName, String actualClazzName) {
		classMaps.put(clazzName, actualClazzName);
	}

	private Map<String, AbstractThreadPool> threadPools = new HashMap<String, AbstractThreadPool>();

	private static QueueThreadPoolManager queueThreadPoolManager = new QueueThreadPoolManager();

	private QueueThreadPoolManager() {

	}

	public static QueueThreadPoolManager getInstance() {
		return queueThreadPoolManager;
	}

	/**
	 * 启动线程池
	 * 
	 * @param queueName
	 * @param queueCode//队列编号
	 * @param processClass
	 * @param actualProcessClass
	 * @param threadCount
	 * @param runStartTime
	 * @param runEndTime
	 * @param sleepTime
	 */
	public synchronized void startThreadPool(String queueName, String queueCode, String processClass,
			String actualProcessClass, int threadCount, String runStartTime, String runEndTime, int sleepTime) {

		AbstractThreadPool threadPool = threadPools.get(queueCode);

		if (threadPool == null || threadPool.getThreadPoolState() == ThreadStatusEnum.TERMINATED.getValue()) {// 线程池不存在或者已终止
			try {
				threadPool = (AbstractThreadPool) Class.forName(actualProcessClass).newInstance();
				threadPool.setPretendClass(processClass);
			} catch (Exception e) {
				logger.error("队列线程池（" + queueCode + "）的处理类初始化失败！", e);
				throw new ThreadPoolException("队列线程池（" + queueCode + "）的处理类初始化失败！");
			}
			threadPool.init(queueName, queueCode, threadCount, runStartTime, runEndTime, sleepTime);// 初始化线程池

			logger.info("开始启动队列线程池，队列线程池名称：" + queueName);
			threadPools.put(queueCode, threadPool);
			threadPool.start();
			logger.info("队列线程池启动完成，队列线程池名称：" + queueName);
		} else {
			logger.warn("队列线程池（" + queueCode + "）已启动！");
			throw new ThreadPoolException("队列线程池（" + queueCode + "）已启动！");
		}
	}

	/**
	 * 停止线程池
	 * 
	 * @param queueCode
	 */
	public void stopThreadPool(String queueCode) {
		AbstractThreadPool threadPool = threadPools.get(queueCode);
		if (threadPool != null && threadPool.getThreadPoolState() != ThreadStatusEnum.TERMINATED.getValue()) {
			logger.info("接收到停止线程池指令，线程池名称：" + threadPool.getThreadPoolName());
			threadPool.stopThreadPool();
			logger.info("线程池已停止，线程池名称：" + threadPool.getThreadPoolName());
		} else {
			logger.warn("队列线程池（" + queueCode + "）不存在或已终止！");
			throw new ThreadPoolException("队列线程池（" + queueCode + "）不存在或已终止！");
		}
	}

	/**
	 * 获取线程池状态
	 * 
	 * @param queueCode
	 * @return
	 */
	public int getThreadPoolState(String queueCode) {
		AbstractThreadPool threadPool = threadPools.get(queueCode);
		if (threadPool == null) {
			return ThreadStatusEnum.TERMINATED.getValue();
		} else {
			return threadPool.getThreadPoolState();
		}
	}

	public ThreadPoolStatus getThreadPoolStatus(String queueCode) {
		AbstractThreadPool threadPool = threadPools.get(queueCode);
		if (threadPool == null) {
			return new ThreadPoolStatus(queueCode,ThreadStatusEnum.TERMINATED.getValue(), 0, 0);
		} else {
			return new ThreadPoolStatus(queueCode,threadPool.getThreadPoolState(), threadPool.getProcessingTaskCount(),
					threadPool.getScheduledTaskCount());
		}
	}

	/**
	 * 获取所有队列线程池状态
	 * 
	 * @return
	 */
	public Map<String, ThreadPoolStatus> getAllThreadPoolStatus() {
		Map<String, ThreadPoolStatus> threadPoolStatusMap = new HashMap<String, ThreadPoolStatus>();
		for (String queueCode : threadPools.keySet()) {
			AbstractThreadPool threadPool = threadPools.get(queueCode);
			ThreadPoolStatus status = new ThreadPoolStatus(queueCode,threadPool.getThreadPoolState(),
					threadPool.getProcessingTaskCount(), threadPool.getScheduledTaskCount());
			threadPoolStatusMap.put(queueCode, status);
		}
		return threadPoolStatusMap;
	}

	/**
	 * 停止所有队列线程池
	 */
	public void stopAllThreadPools() {
		for (String queueCode : threadPools.keySet()) {
			AbstractThreadPool threadPool = threadPools.get(queueCode);
			threadPool.stopThreadPool();
		}
	}

	/**
	 * 查找对应的线程池处理类，用于兼容旧版本的类名
	 * 
	 * @param className
	 * @return
	 */
	public static String getProcessClass(String className) {
		if (classMaps.containsKey(className)) {
			return classMaps.get(className);
		} else {
			return className;
		}
	}
	
	/**
	 * 获取线程池队列中的大小
	 * 
	 * @return
	 */
	public int getQueueThreadPoolSize() {
       return classMaps.size();
    }

}
